package com.chaosj.tools

import com.google.common.base.Strings
import com.google.common.collect.Lists
import com.thoughtworks.xstream.XStream
import com.thoughtworks.xstream.annotations.XStreamAlias
import com.thoughtworks.xstream.annotations.XStreamAsAttribute
import com.thoughtworks.xstream.annotations.XStreamImplicit
import com.thoughtworks.xstream.io.xml.StaxDriver

import java.nio.charset.Charset
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption

/**
 * @Description:
 * @author: caoyangjie
 * @date: 2019年11月2019/11/28日 19:43
 * @Copyright: © 赢时胜
 */
class HelpGenerateHeadKeys {

    static void main(args){
        String xmlStrings = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<ListHeaders>\n" +
                "\t<ListHeader id='pubvocabulary' desc='词汇类型的列头'>\n" +
                "\t\t<Header key='C_DV_CODE' text='词汇代码' align='L' format=''\n" +
                "\t\t\tshowConvert=\"false\"></Header>\n" +
                "\t\t<Header key='C_DV_NAME' text='词汇名称' align='L' format=''></Header>\n" +
                "\t\t<Header key='C_DV_TYPE' text='词汇代码' align='L' format=''></Header>\n" +
                "\t\t<Header key='FEE_TYPE' text='费用类型' align='L' format=''></Header>\n" +
                "\t\t<Header key='orgCodeType' text='机构类型' align='L' format=''></Header>\n" +
                "\t\t<Header key='MKT_TYPE' text='市场类型' align='L' format=''></Header>\n" +
                "\t\t<Header key='ta_sellnetType' text='网点类型' align='L' format=''></Header>\n" +
                "\t\t<Header key='gradedType' text='分级类型' align='L' format=''></Header>\n" +
                "\t\t<Header key='assetType' text='资产类型' align='L' format=''></Header>\n" +
                "\t</ListHeader>"
        // 调用 XmlFileCollectRewrite groovy脚本生成的 汇总 list_head.xml 文件的路径
        String xmlFilePath = "E:\\tmp\\xml\\list_head.xml"
        List<String> listArgs = Arrays.asList(
                // # 前： 要添加 HeadKeys注解的 Java类文件路径,这个路径的文件 可以通过 BasePojoSubClassRewrite 生成
                // # 后： 去 list_head.xml 中查找 <ListHeader id="#后面的值">
                "E:\\tmp\\User.java#usermanage"
        )
        // 追加 @HeadKey 注解到 BasePojo 对象中
        appendHeadKeyToBasePojo(listArgs, xmlFilePath)
    }

    private static void appendHeadKeyToBasePojo(List<String> listArgs, String xmlFilePath) {
        listArgs.stream().forEach({ lineArgs ->
            String writeFilePath = lineArgs.split("#")[0]
            String finder = lineArgs.split("#")[1]

            XStream stream = createXStreamInstance()
            ListHeads heads = stream.fromXML(new File(xmlFilePath))
            ListHead header = heads.list.stream().filter({ head -> head.id == finder }).findAny()
                    .orElseThrow({ throw new RuntimeException(Strings.lenientFormat("未能找到%s的ListHeader配置信息", finder)) })
            File file = new File(writeFilePath)
            if (!file.exists()) {
                throw new RuntimeException(Strings.lenientFormat("当前给定目标类路径[%s]不存在文件", writeFilePath))
            }
            Path filePath = file.toPath()
            List<String> allLines = Files.readAllLines(filePath, Charset.forName("UTF-8"))
            List<String> iterations = Lists.newArrayList(allLines)
            for (int i = 0; i < iterations.size(); i++) {
                String line = iterations.get(i)
                if (line.contains("public class") && line.contains("BasePojo")) {
                    generateListHeads(header, allLines, i)
                    break
                }
            }
            Files.delete(filePath)
            Files.write(filePath,allLines, StandardOpenOption.CREATE_NEW)
        })
    }

    private static void generateListHeads(ListHead header, List<String> allLine, int addIndex){
        String listHead = Strings.lenientFormat("@ListHead(id = \"%s\", desc = \"%s\")",header.id,header.desc)
        allLine.add(addIndex,listHead)
        allLine.add(++addIndex,"@HeadKeys({")
        header.heads.stream().forEach({head->
            allLine.add(++addIndex,generateHeadKey(head))
        })
        allLine.add(++addIndex,"})")
    }

    private static String generateHeadKey(Head headKeys){
        Strings.lenientFormat("    @HeadKey(key = \"%s\",fieldName = \"%s\",text = \"%s\", serviceId = \"%s\", dictAppName = ConvertKeyTarget.OSGI)",
                headKeys.key,headKeys.key, Strings.nullToEmpty(headKeys.text), Strings.nullToEmpty(headKeys.serivceId))
    }

    private static XStream createXStreamInstance() {
        XStream stream = new XStream(new StaxDriver())
        stream.alias("ListHeaders", ListHeads.class)
        stream.alias("ListHeader", ListHead.class)
        stream.alias("Header", Head.class)
        stream.processAnnotations(ListHeads.class)
        stream.processAnnotations(ListHead.class)
        stream.processAnnotations(Head.class)
        stream
    }

    @XStreamAlias("ListHeaders")
    static class ListHeads {

        @XStreamImplicit(itemFieldName = "ListHeader")
        private List<ListHead> list
    }

    static class ListHead{
        @XStreamAsAttribute
        @XStreamAlias("id")
        private String id
        @XStreamAsAttribute
        @XStreamAlias("desc")
        private String desc
        @XStreamImplicit(itemFieldName = "Header")
        private List<Head> heads
    }


    static class Head{
        @XStreamAlias("key")
        @XStreamAsAttribute
        private String key
        @XStreamAlias("text")
        @XStreamAsAttribute
        private String text
        @XStreamAlias("align")
        @XStreamAsAttribute
        private String align
        @XStreamAlias("format")
        @XStreamAsAttribute
        private String format
        @XStreamAlias("isShow")
        @XStreamAsAttribute
        private String isShow
        @XStreamAlias("serviceId")
        @XStreamAsAttribute
        private String serivceId
        @XStreamAlias("showName")
        @XStreamAsAttribute
        private String showName
        @XStreamAlias("typeCode")
        @XStreamAsAttribute
        private String typeCode
    }

}
